package com.zyx.spring5msb.aopbasic.proxy;

import com.zyx.spring5msb.aopbasic.service.Calculator;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

/**
 * @author Yaxi.Zhang
 * @since 2021/9/28 13:39
 * desc: 帮助Calculator生成代理对象的类
 */
public class CalculatorProxy {
    public static Calculator getProxy(final Calculator calculator) {
        // 被代理对象的类加载器
        ClassLoader loader = calculator.getClass().getClassLoader();
        // 被代理对象的接口
        Class<?>[] interfaces = calculator.getClass().getInterfaces();
        // 方法执行器，执行被代理对象的目标方法
        InvocationHandler handler = new InvocationHandler() {
            /**
             * 执行目标方法
             *
             * @param proxy  代理对象，给jdk使用，任何时候都不要操作此对象
             * @param method 当前将要执行的目标对象的方法
             * @param args   这个方法调用时外界传入的参数值
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // 利用反射执行目标方法,目标方法执行后的返回值
                Object result = null;
                try {
                    System.out.println(method.getName() + "方法开始执行，参数是：" + Arrays.asList(args));
                    result = method.invoke(calculator, args);
                    System.out.println(method.getName() + "方法执行完成，结果是：" + result);
                } catch (Exception e) {
                    System.out.println(method.getName() + "方法出现异常：" + e.getMessage());
                } finally {
                    System.out.println(method.getName() + "方法执行结束了......");
                }
                // 将结果返回回去
                return result;
            }
        };
        return (Calculator) Proxy.newProxyInstance(loader, interfaces, handler);
    }

}


